package com.micro.frog.acct.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.micro.frog.acct.dao.MenuMapper;
import com.micro.frog.acct.dao.RoleMenuMapper;
import com.micro.frog.acct.dao.UserRoleMapper;
import com.micro.frog.acct.dto.MenuDTO;
import com.micro.frog.acct.entity.Menu;
import com.micro.frog.acct.entity.RoleMenu;
import com.micro.frog.acct.entity.User;
import com.micro.frog.acct.entity.UserRole;
import com.micro.frog.acct.enums.UserTypeEnum;
import com.micro.frog.acct.service.MenuService;
import com.micro.frog.acct.vo.MenuTreeVO;
import com.micro.frog.acct.vo.MenuVO;
import com.micro.frog.core.common.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author :  ljh
 * @date : 2018/4/2
 **/
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    MenuMapper menuMapper;
    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    RoleMenuMapper roleMenuMapper;

    @Override
    public List<MenuVO> userMenus(User user) {
        List<MenuVO> menuVOS = new ArrayList<>();
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        List<UserRole> list = userRoleMapper.selectByCondition(userRole);
        if (!CollectionUtils.isEmpty(list)){
            List<Integer> roleIds = new ArrayList<>();
            list.forEach(a -> roleIds.add(a.getRoleId()));
            List<RoleMenu> roleMenus = roleMenuMapper.selectByRoleIdIn(roleIds);
            List<Integer> menuIds = new ArrayList<>();
            if (!CollectionUtils.isEmpty(roleMenus)){
                roleMenus.forEach(a -> menuIds.add(a.getMenuId()));
            }
            List<Menu> menus = menuMapper.selectIdIn(menuIds);
            menuVOS = buildMenuVo(menus);
        } else {
            //超级管理员强制拥有所有菜单
            if (UserTypeEnum.SUPER_ADMIN.getCode().equals(user.getType())) {
                return buildMenuVo(menuMapper.selectAll());
            }
        }
        return menuVOS;
    }

    @Override
    public List<MenuVO> queryAll() {
        List<Menu> list = menuMapper.selectAll();
        List<MenuVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)){
            for (Menu menu : list) {
                MenuVO vo = new MenuVO();
                BeanUtils.copyProperties(menu,vo);
                vos.add(vo);
            }
        }
        return vos;
    }

    @Override
    public PageResult list(MenuDTO queryVO) {
        queryVO.init();
        Page page = PageHelper.startPage(queryVO.getPageNum(),queryVO.getPageSize(),true);
        List<MenuVO> list = menuMapper.selectByCondition(queryVO);
        PageResult pageResult = new PageResult();
        pageResult.setTotal(page.getTotal());
        pageResult.setData(list);
        pageResult.setCode("10000");
        pageResult.setMsg("成功");
        return pageResult;
    }

    @Override
    public int addMenu(MenuVO menuVO) {
        Menu menu = new Menu();
        final Date current = new Date();
        BeanUtils.copyProperties(menuVO,menu);
        menu.setCreatedTime(current);
        menu.setUpdatedTime(current);
        return menuMapper.insertSelective(menu);
    }

    @Override
    public int deleteMenu(Integer menuId) {
        Menu menu = new Menu();
        menu.setId(menuId);
        menu.setIsDeleted("Y");
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public int updateMenu(MenuVO menuVO) {
        Menu menu = new Menu();
        final Date current = new Date();
        BeanUtils.copyProperties(menuVO,menu);
        menu.setUpdatedTime(current);
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public List<MenuTreeVO> tree() {
        List<MenuTreeVO> vos = new ArrayList<>();
        List<Menu> data = menuMapper.selectAll();
        if (!CollectionUtils.isEmpty(data)){
            vos = buildTreeVO(data);
        }
        return vos;
    }

    private List<MenuTreeVO> buildTreeVO(List<Menu> box){
        List<MenuTreeVO> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(box)){
            for (int i = 0; i < box.size(); i++) {
                Menu menu = box.get(i);
                if (menu != null && menu.getPid() == 0){
                    MenuTreeVO treeVO = new MenuTreeVO();
                    treeVO.setTitle(menu.getName());
                    treeVO.setValue(menu.getId());
                    treeVO.setData(buildSubTree(box, menu.getId()));
                    list.add(treeVO);
                }
            }
        }
        return list;
    }
    private List<MenuTreeVO> buildSubTree(List<Menu> box, Integer pid){
        List<MenuTreeVO> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(box)){
            for (int i = 0; i < box.size(); i++) {
                Menu menu = box.get(i);
                if (menu != null && pid.equals(menu.getPid())){
                    MenuTreeVO treeVO = new MenuTreeVO();
                    treeVO.setTitle(menu.getName());
                    treeVO.setValue(menu.getId());
                    treeVO.setData(buildSubTree(box, menu.getId()));
                    list.add(treeVO);
                }
            }
        }
        return list;
    }

    private  List<MenuVO> buildMenuVo(List<Menu> menus){
        List<MenuVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menus)){
            Iterator<Menu> iterator = menus.iterator();
            while (iterator.hasNext()){
                Menu menu = iterator.next();
                MenuVO vo = new MenuVO();
                if ((null == menu.getLevel() || 0 == menu.getLevel())&& ( null == menu.getPid() || 0 == menu.getPid())){
                    BeanUtils.copyProperties(menu,vo);
                    vo.setChildren(buildChildren(menus, vo.getId()));
                    vos.add(vo);
                }
            }
        }
        vos.sort(Comparator.comparing(MenuVO::getSort));
        return vos;
    }

    private List<MenuVO> buildChildren(List<Menu> menus, Integer pid){
        List<MenuVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menus)){
            Iterator<Menu> iterator = menus.iterator();
            while (iterator.hasNext()){
                Menu menu = iterator.next();
                MenuVO vo = new MenuVO();
                if (null != pid && pid.equals(menu.getPid())){
                    BeanUtils.copyProperties(menu,vo);
                    vos.add(vo);
                }
            }
        }
        vos.sort(Comparator.comparing(MenuVO::getSort));
        return vos;
    }
}
